# Web Worker使用
Web Worker可以用来创造多线程环境,允许主线程把一些计算密集型或高延迟的任务分配给Worker线程,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢,两者互不干扰。使用Worker单独开一个js来处理一些占内存耗性能的任务。
Web Worker 有以下几个使用注意点:
同源限制:分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
DOM 限制:Worker线程中无法获取DOM对象,但可以使用navigator和location。
通信联系:Worker线程和主线程不能直接通信,必须通过消息完成。
脚本限制:Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
文件限制:Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。
# 1、创建Worker线程
在主线中我们程使用Worker构造函数加载一个单独的JS文件,新建一个线程。加载的这个JS文件就是Worker线程所要执行的任务。
var worker = new Worker('/work.js');
Worker线程JS文件
// work.js
console.log('worker线程');
# 2、相互通信
主线程和Worker线程之间发送和接收都是通过postMessage方法和监听message事件进行。
Worker 之间的通信内容,可以是文本、对象,也可以是二进制数据,比如 File、Blob、ArrayBuffer 等类型。正常数据通信数据不会相互影响,如果是二进制数据的话,为了节省性能,JS会进行特殊处理,一但传输给子线程后,主线程就无法再使用这些数据。
主线程发送和接收:
var worker = new Worker('/work.js');
// 主线程发送消息
worker.postMessage('Hello World');
worker.postMessage({
name: 'xxx',
age: 18
});
// 主线程接收消息
worker.onmessage = function (event) {
// event.data 就是接受的数据
console.log(event.data);
};
// 监听错误
worker.onerror = function (event) {
console.log(event);
};
Worker线程发送和接收:
// self是子线程的全局对象
// 子线程发送消息
self.postMessage('Hello World');
self.postMessage({
name: '111',
age: 111
});
// 子线程接收消息
self.onmessage = function (event) {
// event.data 就是接受的数据
console.log(event.data);
};
// 监听错误
self.onerror = function (event) {
console.log(event);
};
# 3、Worker中加载脚本
Worker 内部如果要加载其他脚本,有一个专门的方法importScripts()。
// 加载脚本
self.importScripts("/spark-md5.min.js");
// 加载多个脚本
self.importScripts('script1.js', 'script2.js');
# 4、关闭Worker
使用完成后,为了节省系统资源,必须关闭 Worker。
// 主线程
worker.terminate();
// Worker线程
self.close();